#include "light_sensor.h"
#include "SysTick.h"

ADC_HandleTypeDef ADC3_Handler;			// ADC句柄

/***************************
* 函数名： LightSensor_Init
* 功能：初始化光敏传感器
* 输入：无
* 输出：无
*/
void LightSensor_Init(void)
{
	RCC_PeriphCLKInitTypeDef ADC_CLKInit;
	ADC_CLKInit.PeriphClockSelection=RCC_PERIPHCLK_ADC;							// ADC外设时钟
	ADC_CLKInit.AdcClockSelection=RCC_ADCPCLK2_DIV6;								// 分频因子6时钟为72M/6
	HAL_RCCEx_PeriphCLKConfig(&ADC_CLKInit);												// 设置ADC时钟
	
	ADC3_Handler.Instance=ADC3;
	ADC3_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;								// 右对齐
	ADC3_Handler.Init.ScanConvMode=DISABLE;													// 非扫描模式
	ADC3_Handler.Init.ContinuousConvMode=DISABLE;										// 关闭连续转换
	ADC3_Handler.Init.NbrOfConversion=1;														// 1个转换在规则序列中，即只转换规则序列1
	ADC3_Handler.Init.DiscontinuousConvMode=DISABLE;								// 禁止不连续采样模式
	ADC3_Handler.Init.NbrOfDiscConversion=0;												// 不连续采样通道数为0
	ADC3_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;					// 软件触发
	HAL_ADC_Init(&ADC3_Handler);																		// 初始化
	
	HAL_ADCEx_Calibration_Start(&ADC3_Handler);											// 校准ADC
}

/*******************************************
* ADC底层驱动，引脚配置，时钟使能
* 该函数被HAL_ADC_Init()调用
* hadc：ADC句柄
********************************************/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	__HAL_RCC_ADC3_CLK_ENABLE();								// 使能ADC3时钟
	__HAL_RCC_GPIOF_CLK_ENABLE();								// 使能GPIOF时钟
	
	GPIO_InitStructure.Pin=GPIO_PIN_8;					// PF8
	GPIO_InitStructure.Mode=GPIO_MODE_ANALOG;		// 模拟
	GPIO_InitStructure.Pull=GPIO_NOPULL;				// 不带上下拉
	HAL_GPIO_Init(GPIOF,&GPIO_InitStructure);
}

/****************************************************
* 获取ADC值
* ch：通道值0~16，范围：ADC_CHANNEL_0~ADC_CHANNEL_16
* 返回：转换结果
*****************************************************/
u16 Get_Adc3(u32 ch)
{
	ADC_ChannelConfTypeDef ADC3_ChanConf;
	ADC3_ChanConf.Channel=ch;															// 通道
	ADC3_ChanConf.Rank=1;																	// 第1个序列，序列1
	ADC3_ChanConf.SamplingTime=ADC_SAMPLETIME_239CYCLES_5;	// 采样时间
	HAL_ADC_ConfigChannel(&ADC3_Handler,&ADC3_ChanConf);		// 通道配置
	
	HAL_ADC_Start(&ADC3_Handler);													// 开启ADC
	HAL_ADC_PollForConversion(&ADC3_Handler,10);					// 轮询转换
	
	return (u16)HAL_ADC_GetValue(&ADC3_Handler);					// 返回最近一次ADC3规则组转换结果
}

#define LIGHT_SENSOR_READ_TIMES				10				// 光敏传感器读取次数，取该次数平均值

/*******************************************
* 读取光敏传感器值
* 0~100：0最暗，100最亮
*******************************************/
u8 LightSensor_Get_Val(void)
{
	u32 temp_val=0;
	u8 t=0;
	for(t=0;t<LIGHT_SENSOR_READ_TIMES;t++)
	{
		temp_val += Get_Adc3(ADC_CHANNEL_6);			// 读取ADC，通道6上的值
		delay_ms(5);
	}
	temp_val = temp_val/LIGHT_SENSOR_READ_TIMES; // 平均值
	if(temp_val > 4000) temp_val=4000;
	return (u8)(100-(temp_val/40));
}